/**
 * @projectName ApexX-Cloud
 * @package com.apex.shared.starter.config
 * @className com.apex.shared.starter.config.UndertowConfig
 * @copyright Copyright 2020 Thunisoft, Inc All rights reserved.
 */
package com.apex.shared.starter.config;

import io.undertow.server.DefaultByteBufferPool;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.env.Environment;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Undertow 服务器配置类
 * 1. 配置 WebSocket 缓冲池，解决 UT026010 警告
 * 2. 支持 Java 21 虚拟线程
 * 3. 优化服务器性能配置
 *
 * @author MoNaiHui
 */
@Slf4j
@AutoConfiguration
public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    private static final String VIRTUAL_THREAD_PROPERTY = "spring.threads.virtual.enabled";
    private static final int BUFFER_SIZE = 2048;
    private static final String THREAD_NAME_PREFIX = "undertow-virtual-thread-";
    
    @Resource
    private Environment environment;

    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        factory.addDeploymentInfoCustomizers(this::customizeDeploymentInfo);
    }

    /**
     * 自定义 Undertow 部署信息
     * @param deploymentInfo Undertow 部署信息对象
     */
    private void customizeDeploymentInfo(DeploymentInfo deploymentInfo) {
        optimizeServletConfig(deploymentInfo);
        configureWebSocket(deploymentInfo);
        configureVirtualThreads(deploymentInfo);
    }

    /**
     * 优化 Servlet 配置
     * 禁用非标准包装器以提高安全性
     */
    private void optimizeServletConfig(DeploymentInfo deploymentInfo) {
        deploymentInfo.setAllowNonStandardWrappers(false);
    }

    /**
     * 配置 WebSocket
     * 设置 WebSocket 缓冲池，避免 UT026010 警告
     */
    private void configureWebSocket(DeploymentInfo deploymentInfo) {
        WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo()
                .setBuffers(new DefaultByteBufferPool(true, BUFFER_SIZE));
        
        deploymentInfo.addServletContextAttribute(
                WebSocketDeploymentInfo.ATTRIBUTE_NAME, 
                webSocketDeploymentInfo
        );
    }

    /**
     * 配置虚拟线程支持
     * 为 Undertow 设置虚拟线程执行器
     */
    private void configureVirtualThreads(DeploymentInfo deploymentInfo) {
        if (!isVirtualThreadsSupported()) {
            return;
        }

        var virtualThreadExecutor = createVirtualThreadExecutor();
        deploymentInfo.setExecutor(virtualThreadExecutor);
        deploymentInfo.setAsyncExecutor(virtualThreadExecutor);
        
        log.info("已启用 Undertow 虚拟线程支持，使用共享虚拟线程执行器");
    }

    /**
     * 检查是否支持并启用虚拟线程
     * 需要 Java 21+ 且配置项启用
     */
    private boolean isVirtualThreadsSupported() {
        boolean isEnabled = Boolean.parseBoolean(
                environment.getProperty(VIRTUAL_THREAD_PROPERTY, "false")
        );
        return Runtime.version().feature() >= 21 && isEnabled;
    }

    /**
     * 创建虚拟线程工厂
     * 用于生成带有自定义命名的虚拟线程
     */
    private ThreadFactory createVirtualThreadFactory() {
        AtomicInteger threadCounter = new AtomicInteger(1);
        return runnable -> Thread.ofVirtual()
                .name(THREAD_NAME_PREFIX + threadCounter.getAndIncrement())
                .unstarted(runnable);
    }

    /**
     * 创建虚拟线程执行器
     * 返回基于虚拟线程的执行器实例
     */
    private Executor createVirtualThreadExecutor() {
        return Executors.newThreadPerTaskExecutor(createVirtualThreadFactory());
    }
}


 